/**
 * @file IRGenerator.cpp
 * @author zenglj (zenglj@nwpu.edu.cn)
 * @brief AST遍历产生线性IR
 * @version 0.1
 * @date 2023-09-24
 *
 * @copyright Copyright (c) 2023
 *
 */
#include <cerrno>
#include <cstdint>
#include <cstdio>
#include <iostream>
#include <iterator>
#include <ostream>
#include <string>
#include <system_error>
#include <unordered_map>
#include <vector>

#include "AST.h"
#include "IRCode.h"
#include "IRGenerator.h"
#include "IRInst.h"
#include "SymbolTable.h"
#include "Value.h"
#include "ValueType.h"

/// @brief 构造函数
/// @param _root AST的根
/// @param _symtab 符号表
IRGenerator::IRGenerator(ast_node * _root, SymbolTable * _symtab) : root(_root), symtab(_symtab)
{
    /* 叶子节点 */
    ast2ir_handlers[ast_operator_type::AST_OP_LEAF_LITERAL_UINT] = &IRGenerator::ir_leaf_node_uint;
    ast2ir_handlers[ast_operator_type::AST_OP_LEAF_LITERAL_FLOAT] = &IRGenerator::ir_leaf_node_float;
    ast2ir_handlers[ast_operator_type::AST_OP_LEAF_VAR_ID] = &IRGenerator::ir_leaf_node_var_id;
    ast2ir_handlers[ast_operator_type::AST_OP_LEAF_VAR_TYPE] = &IRGenerator::ir_leaf_node_var_type;

    /* 变量声明 */
    ast2ir_handlers[ast_operator_type::AST_OP_VARDECL] = &IRGenerator::ir_vardecl;
    ast2ir_handlers[ast_operator_type::AST_OP_VARINIT] = &IRGenerator::ir_varinit;

    /* 表达式运算， 加减乘除余 */
    ast2ir_handlers[ast_operator_type::AST_OP_SUB] = &IRGenerator::ir_sub;
    ast2ir_handlers[ast_operator_type::AST_OP_ADD] = &IRGenerator::ir_add;
    ast2ir_handlers[ast_operator_type::AST_OP_MUL] = &IRGenerator::ir_mul;
    ast2ir_handlers[ast_operator_type::AST_OP_DIV] = &IRGenerator::ir_div;
    ast2ir_handlers[ast_operator_type::AST_OP_MOD] = &IRGenerator::ir_mod;

    /* 关系运算 */
    ast2ir_handlers[ast_operator_type::AST_OP_LTE] = &IRGenerator::ir_lt;
    ast2ir_handlers[ast_operator_type::AST_OP_LTQUAL] = &IRGenerator::ir_le;
    ast2ir_handlers[ast_operator_type::AST_OP_GTE] = &IRGenerator::ir_gt;
    ast2ir_handlers[ast_operator_type::AST_OP_GTEQUAL] = &IRGenerator::ir_ge;
    ast2ir_handlers[ast_operator_type::AST_OP_EQUAL] = &IRGenerator::ir_eq;
    ast2ir_handlers[ast_operator_type::AST_OP_NEQUAL] = &IRGenerator::ir_ne;

    /* 逻辑运算，与或非 */
    ast2ir_handlers[ast_operator_type::AST_OP_AND] = &IRGenerator::ir_and;
    ast2ir_handlers[ast_operator_type::AST_OP_OR] = &IRGenerator::ir_or;
    ast2ir_handlers[ast_operator_type::AST_OP_NOT] = &IRGenerator::ir_not;

    /* 语句 */
    ast2ir_handlers[ast_operator_type::AST_OP_EXPR] = &IRGenerator::ir_expr_noshow;
    ast2ir_handlers[ast_operator_type::AST_OP_EXPR_SHOW] = &IRGenerator::ir_expr_show;
    ast2ir_handlers[ast_operator_type::AST_OP_ASSIGN] = &IRGenerator::ir_assign;
    ast2ir_handlers[ast_operator_type::AST_OP_RETURN_STATEMENT] = &IRGenerator::ir_return;
    ast2ir_handlers[ast_operator_type::AST_OP_IF] = &IRGenerator::ir_if;
    ast2ir_handlers[ast_operator_type::AST_OP_ELSE] = &IRGenerator::ir_else;
    ast2ir_handlers[ast_operator_type::AST_OP_CONDITION] = &IRGenerator::ir_if_condition;
    ast2ir_handlers[ast_operator_type::AST_OP_WHILE] = &IRGenerator::ir_while;

    /* 函数调用 */
    ast2ir_handlers[ast_operator_type::AST_OP_FUNC_CALL] = &IRGenerator::ir_function_call;

    /* 函数定义 */
    ast2ir_handlers[ast_operator_type::AST_OP_FUNC_DEF] = &IRGenerator::ir_function_define;
    ast2ir_handlers[ast_operator_type::AST_OP_FUNC_FORMAL_PARAMS] = &IRGenerator::ir_function_formal_params;
    ast2ir_handlers[ast_operator_type::AST_OP_FUNC_RETURN] = &IRGenerator::ir_function_return_type;

    /* 语句块 */
    ast2ir_handlers[ast_operator_type::AST_OP_BLOCK] = &IRGenerator::ir_block;

    /* 编译单元 */
    ast2ir_handlers[ast_operator_type::AST_OP_COMPILE_UNIT] = &IRGenerator::ir_compile_unit;
}

/// @brief 编译单元AST节点翻译成线性中间IR
/// @param node AST节点
/// @return 翻译是否成功，true：成功，false：失败
bool IRGenerator::ir_compile_unit(ast_node * node)
{
    // 新建main函数并默认设置当前函数为main函数
    // symtab->mainFunc = symtab->newFunction("main", BasicType::TYPE_INT);
    // symtab->currentFunc = symtab->mainFunc;

    // // 获取函数的IR代码列表，用于后面追加指令用，注意这里用的是引用传值
    // InterCode & irCode = symtab->currentFunc->getInterCode();

    // // 创建并加入Entry入口指令
    // irCode.addInst(new EntryIRInst());

    // // 创建出口指令并不加入出口指令，等函数内的指令处理完毕后加入出口指令
    // IRInst * exitLabelInst = new LabelIRInst();
    // symtab->currentFunc->setExitLabel(exitLabelInst);

    // // 新建一个Value，用于保存函数的返回值，如果没有返回值可不用申请，
    // Value * retValue = symtab->currentFunc->newVarValue(BasicType::TYPE_INT);
    // symtab->currentFunc->setReturnValue(retValue);

    for (auto son: node->sons) {

        // 遍历编译单元，要么是函数定义，要么是全局变量声明
        ast_node * son_node = ir_visit_ast_node(son);
        if (!son_node) {
            return false;
        }

        node->blockInsts.addInst(son_node->blockInsts);
    }

    // // 除了函数定义的指令外都加入到main函数的指令当中
    // irCode.addInst(node->blockInsts);

    // // 添加函数出口Label指令，主要用于return语句跳转到这里进行函数的退出
    // irCode.addInst(exitLabelInst);

    // // 尾部追加一个return 0指令，使得main函数的格式正确
    // irCode.addInst(new ExitIRInst(new ConstValue(0)));

    // // main函数移动到列表的尾部，以便后续简便处理
    // symtab->moveFunctionEnd(symtab->mainFunc);

    // 设置成空，使得后续访问该变量出错。
    symtab->currentFunc = nullptr;

    return true;
}

bool IRGenerator::ir_vardecl(ast_node* node) {
    // 确定当前的是否是 全局变量
    if(node->parent == nullptr)
        return false;
    else {
        int cnt = node->sons.size();
        ast_node* type = node->sons[cnt-1];
        type = ir_visit_ast_node(type);
        if(!type) return false;
        for(int i = 0; i < cnt - 1; i++) {
            ast_node* id   = node->sons[i];
            bool declare = create_declare(node, id, type);
            if(!declare) return false;
        }
        // std::cout << "本节点的孩子个数" << node->sons.size() << std::endl;
    }
    return true;
}

bool IRGenerator::ir_varinit(ast_node* node) {
    ast_node* type = node->sons[0];
    ast_node* id = node->sons[1];
    ast_node* expr = node->sons[2];

    type = ir_visit_ast_node(type);
    if(!type) return false;
    bool declare = create_declare(node, id, type);

    if(!declare) return false;

    expr = ir_visit_ast_node(expr);
    if(!expr) return expr;

    // 创建赋值语句
    IRInst* assign = new AssignIRInst(id->val, expr->val);
    // 组装 指令
    node->blockInsts.addInst(expr->blockInsts);
    node->blockInsts.addInst(assign);

    return true;

}

/// @brief 工具类函数
bool IRGenerator::create_declare(ast_node* node, ast_node* id, ast_node* type) {
        id   = ir_visit_ast_node(id);
        if(!id) return false;
        std::string id_name = id->name;
        if(node->parent->node_type == ast_operator_type::AST_OP_COMPILE_UNIT) { // 全局变量
            // 需要在 符号表中 注册这个符号
            // 全局变量的名字有点特殊 @id_name
            std::string gname = "@" + id_name;
            id->val->name = gname;                // 修改全局变量的名字
            id->type = type->type;
            // 向符号表中注册这个全局变量
            symtab->insertValueBy(id_name, id->val);
            // if(symtab->findValue(id_name)) {
            //     std::cout << "符号表中存在变量" << id_name << std::endl;
            // }
            node->val = id->val;
            node->blockInsts.addInst(new DeclareIRInst(node->val));
        } else {
            // 修改局部变量的名字
            std::string lname = Value::createLocalVarName();
            id->val->name = lname;               // 修改局部变量的名字
            id->type = type->type;
            // 向当前函数中注册变量
            symtab->currentFunc->insertValueBy(id_name, id->val);
            node->val = id->val;
            symtab->currentFunc->getInterCode().addInstFirst(new DeclareIRInst(node->val));
        }
        return true;
}

/// @brief 函数定义AST节点翻译成线性中间IR
/// @param node AST节点
/// @return 翻译是否成功，true：成功，false：失败
bool IRGenerator::ir_function_define(ast_node * node)
{
    // 创建一个函数，用于当前函数处理
    if (symtab->mainFunc != nullptr && symtab->currentFunc != symtab->mainFunc) {
        // 函数中嵌套定义函数，这是不允许的，错误退出
        // TODO 自行追加语义错误处理
        std::cout << "Mustn't define a new function within the old function" << std::endl;
        return false;
    }

    // 创建一个新的函数定义，函数的返回类型设置为VOID，待定，必须等return时才能确定，目前可以是VOID或者INT类型
    symtab->currentFunc = new Function(node->name, BasicType::TYPE_VOID);
    // 设定函数所在的符号表
    symtab->currentFunc->setSymtab(symtab);
    bool result = symtab->insertFunction(symtab->currentFunc);
    if (!result) {
        // 清理资源
        delete symtab->currentFunc;

        // 恢复当前函数指向main函数
        symtab->currentFunc = symtab->mainFunc;

        // 函数已经定义过了，不能重复定义，语义错误：出错返回。
        // TODO 自行追加语义错误处理
        std::cout << "The function has been defined!!" << std::endl;

        return false;
    }

    // 获取函数的IR代码列表，用于后面追加指令用，注意这里用的是引用传值
    InterCode & irCode = symtab->currentFunc->getInterCode();

    // 这里也可增加一个函数入口Label指令，便于后续基本块划分

    // 创建一个 Label 标签指令
    irCode.addInst(new LabelIRInst());
    // 创建并加入Entry入口指令
    irCode.addInst(new EntryIRInst());

    // 创建出口指令并不加入出口指令，等函数内的指令处理完毕后加入出口指令
    IRInst * exitLabelInst = new LabelIRInst();

    // 函数出口指令保存到函数信息中，因为在语义分析函数体时return语句需要跳转到函数尾部，需要这个label指令
    symtab->currentFunc->setExitLabel(exitLabelInst);

    // 新建一个Value，用于保存函数的返回值，如果没有返回值可不用申请，
    // 目前未知，先创建一个，不用后续可释放
    Value * retValue = symtab->currentFunc->newVarValue(BasicType::TYPE_INT);
    // 同时向函数中添加 相关变量的声明指令
    IRInst* temp = new DeclareIRInst(retValue);

    // 保存函数返回值变量到函数信息中，在return语句翻译时需要设置值到这个变量中
    symtab->currentFunc->setReturnValue(retValue);

    // 遍历函数体内的每个语句
    for (auto son: node->sons) {

        // 遍历函数定义，孩子要么是形式参数，要么是block
        ast_node * son_node = ir_visit_ast_node(son);
        if (!son_node) {

            // 对函数体内的语句进行语义分析时出现错误
            return false;
        }

        // IR指令追加到当前的节点中
        node->blockInsts.addInst(son_node->blockInsts);
    }

    // 此时，所有指令都加入到当前函数中，也就是node->blockInsts

    // node节点的指令移动到函数的IR指令列表中
    irCode.addInst(node->blockInsts);

    // 添加函数出口Label指令，主要用于return语句跳转到这里进行函数的退出
    irCode.addInst(exitLabelInst);

    // 检查函数是否有返回值类型，则需要设置返回值，否则不设置
    if (symtab->currentFunc->getReturnType().type != BasicType::TYPE_VOID) {
        // 将当前的临时变量的声明指令添加到 当前函数的指令块中
        symtab->currentFunc->getInterCode().addInstFirst(temp);
        // 函数出口指令
        irCode.addInst(new ExitIRInst(retValue));
    } else {
        // 清理资源恢复原状
        symtab->currentFunc->deleteVarValue(retValue);
        symtab->currentFunc->setReturnValue(nullptr);
        delete retValue;
        delete temp;

        // 函数出口指令
        irCode.addInst(new ExitIRInst());
    }

    // 恢复成指向main函数
    symtab->currentFunc = symtab->mainFunc;

    return true;
}

/// @brief 形式参数AST节点翻译成线性中间IR
/// @param node AST节点
/// @return 翻译是否成功，true：成功，false：失败
bool IRGenerator::ir_function_formal_params(ast_node * node)
{
    // 获取当前要保存函数的形式参数清单
    auto & params = symtab->currentFunc->getParams();

    // 遍历形式参数列表，孩子是叶子节点
    for (auto son: node->sons) {

        // 创建变量，默认整型
       Value* var = new VarValue(BasicType::TYPE_INT);
       // 向函数中进行注册 
       symtab->currentFunc->insertValueBy(son->name, var);
        // 形参类型的声明也需要在注册一个局部变量
         // 同时向函数中添加 相关变量的声明指令
        IRInst* temp = new DeclareIRInst(var);  // 需要手动注册局部变量
        // 将当前的临时变量的声明指令添加到 当前函数的指令块中
        symtab->currentFunc->getInterCode().addInstFirst(temp);

        // 创建此时的形式参数的中间编号
       Value* tmp = symtab->currentFunc->newTempValue(BasicType::TYPE_INT);
        // 默认是整数类型
        params.emplace_back(tmp->getName(), BasicType::TYPE_INT, var);

        // 简单处理，无论如何我们首先都会对 局部变量进行赋值处理
        IRInst* assign = new AssignIRInst(var, tmp);
        // 将当前赋值指令加入到 当前函数中
        symtab->currentFunc->getInterCode().addInst(assign);
    }

    return true;
}

/// @brief 函数返回类型AST节点翻译成线性中间IR
/// @param node AST节点
/// @return 翻译是否成功，true：成功，false：失败
bool IRGenerator::ir_function_return_type(ast_node* node) {
    // TODO ： 将函数定义节点中返回类型进行动态修改
    ast_node* ret_type = node->sons[0];
    ret_type = ir_visit_ast_node(ret_type);
    if(!ret_type) return false;     // 存在 语法错误

    // 遍历 类型叶子节点 并获取类型信息
    switch (ret_type->type.type) {
        case BasicType::TYPE_INT : 
            symtab->currentFunc->setReturnType(ret_type->type);
            break;
        case BasicType::TYPE_VOID :
            symtab->currentFunc->setReturnType(ret_type->type);
            break;
        default:
            std::cout << "minic 不支持这种返回值类型" << std::endl;
    }
    return true;
}

/// @brief 函数调用AST节点翻译成线性中间IR
/// @param node AST节点
/// @return 翻译是否成功，true：成功，false：失败
bool IRGenerator::ir_function_call(ast_node * node)
{
    std::vector<Value *> realParams;

    // 根据函数名查找函数，看是否存在。若不存在则出错
    // 这里约定函数必须先定义后使用
    auto pFunction = symtab->findFunction(node->name);
    if (nullptr == pFunction) {
        // TODO 这里输出错误信息
        std::cout << "调用了未被定义的函数" << std::endl;
        return false;
    }

    // 设置存在函数调用
    symtab->currentFunc->setExistFuncCall(true);

    // 如果没有孩子，也认为是没有参数
    if (!node->sons.empty()) {

        // 只有一个节点，实际参数列表
        auto paramsNode = node->sons[0];

        int argsCount = (int) paramsNode->sons.size();

        // 设置最大函数调用参数个数
        if (argsCount > symtab->currentFunc->getMaxFuncCallArgCnt()) {
            symtab->currentFunc->setMaxFuncCallArgCnt(argsCount);
        }

        // 遍历参数列表，孩子是表达式
        // 这里自左往右计算表达式
        for (auto son: paramsNode->sons) {

            // 遍历Block的每个语句，进行显示或者运算
            ast_node * temp = ir_visit_ast_node(son);
            if (!temp) {
                return false;
            }

            realParams.push_back(temp->val);
            node->blockInsts.addInst(temp->blockInsts);
        }
    }

    // 创建临时变量，用于保存函数调用的结果
    Value * resultVal = nullptr;

    // 返回调用有返回值，则需要分配临时变量
    if (pFunction->getReturnType().type == BasicType::TYPE_INT) {
        resultVal = symtab->currentFunc->newTempValue(BasicType::TYPE_INT);
        // 同时向函数中添加 相关变量的声明指令
        IRInst* temp = new DeclareIRInst(resultVal);
        // 将当前的临时变量的声明指令添加到 当前函数的指令块中
        symtab->currentFunc->getInterCode().addInstFirst(temp);
    }

    // 创建函数调用指令
    node->blockInsts.addInst(new FuncCallIRInst(node->name, realParams, resultVal));

    // 设置存在函数调用，后面要根据是否函数调用进行调整栈分配策略
    symtab->currentFunc->setExistFuncCall(true);

    // 函数调用结果保存到node中，用于外部使用
    node->val = resultVal;

    return true;
}

/// @brief 语句块（含函数体）AST节点翻译成线性中间IR
/// @param node AST节点
/// @return 翻译是否成功，true：成功，false：失败
bool IRGenerator::ir_block(ast_node * node)
{
    std::vector<ast_node *>::iterator pIter;
    for (pIter = node->sons.begin(); pIter != node->sons.end(); ++pIter) {

        // 遍历Block的每个语句，进行显示或者运算
        ast_node * temp = ir_visit_ast_node(*pIter);
        if (!temp) {
            return false;
        }

        node->blockInsts.addInst(temp->blockInsts);
    }

    return true;
}

/// @brief 表达式语句ST节点翻译成线性中间IR的共同函数
/// @param node AST节点
/// @param show 是否显示值，true：显示，false：不显示
/// @return 翻译是否成功，true：成功，false：失败
bool IRGenerator::ir_show_internal(ast_node * node, bool show)
{
    // TODO real number print

    ast_node * src1_node = node->sons[0];

    ast_node * result = ir_visit_ast_node(src1_node);
    if (!result) {
        // 解析错误
        return false;
    }

    node->blockInsts.addInst(result->blockInsts);

    if (show && (result->val != nullptr)) {

        // 创建函数调用指令
        node->blockInsts.addInst(new FuncCallIRInst("putint", result->val));

        // 设置存在函数调用，后面要根据是否函数调用进行调整栈分配策略
        symtab->currentFunc->setExistFuncCall(true);
    }

    node->val = nullptr;

    return true;
}

/// @brief 不显示表达式AST节点翻译成线性中间IR
/// @param node AST节点
/// @return 翻译是否成功，true：成功，false：失败
bool IRGenerator::ir_expr_noshow(ast_node * node)
{
    return ir_show_internal(node, false);
}

/// @brief 显示表达式AST节点翻译成线性中间IR
/// @param node AST节点
/// @return 翻译是否成功，true：成功，false：失败
bool IRGenerator::ir_expr_show(ast_node * node)
{
    return ir_show_internal(node, true);
}

/// @brief 整数加法AST节点翻译成线性中间IR
/// @param node AST节点
/// @return 翻译是否成功，true：成功，false：失败
bool IRGenerator::ir_add(ast_node * node)
{
    ast_node * src1_node = node->sons[0];
    ast_node * src2_node = node->sons[1];

    // 加法节点，左结合，先计算左节点，后计算右节点

    // 加法的左边操作数
    ast_node * left = ir_visit_ast_node(src1_node);
    if (!left) {
        // 某个变量没有定值
        return false;
    }

    // 加法的右边操作数
    ast_node * right = ir_visit_ast_node(src2_node);
    if (!right) {
        // 某个变量没有定值
        return false;
    }

    // 这里只处理整型的数据，如需支持实数，则需要针对类型进行处理
    // TODO real number add

    Value * resultValue = symtab->currentFunc->newTempValue(BasicType::TYPE_INT);
    // 同时向函数中添加 相关变量的声明指令
    IRInst* temp = new DeclareIRInst(resultValue);
    // 将当前的临时变量的声明指令添加到 当前函数的指令块中
    symtab->currentFunc->getInterCode().addInstFirst(temp);

    // 创建临时变量保存IR的值，以及线性IR指令
    node->blockInsts.addInst(left->blockInsts);
    node->blockInsts.addInst(right->blockInsts);
    node->blockInsts.addInst(new BinaryIRInst(IRInstOperator::IRINST_OP_ADD_I, resultValue, left->val, right->val));
    node->val = resultValue;

    return true;
}

/// @brief 整数减法AST节点翻译成线性中间IR
/// @param node AST节点
/// @return 翻译是否成功，true：成功，false：失败
bool IRGenerator::ir_sub(ast_node * node)
{
    ast_node * src1_node = node->sons[0];
    ast_node * src2_node = node->sons[1];

    // 加法节点，左结合，先计算左节点，后计算右节点

    // 加法的左边操作数
    ast_node * left = ir_visit_ast_node(src1_node);
    if (!left) {
        // 某个变量没有定值
        return false;
    }

    // 加法的右边操作数
    ast_node * right = ir_visit_ast_node(src2_node);
    if (!right) {
        // 某个变量没有定值
        return false;
    }

    // 这里只处理整型的数据，如需支持实数，则需要针对类型进行处理
    // TODO real number add

    Value * resultValue = symtab->currentFunc->newTempValue(BasicType::TYPE_INT);
    // 同时向函数中添加 相关变量的声明指令
    IRInst* temp = new DeclareIRInst(resultValue);
    // 将当前的临时变量的声明指令添加到 当前函数的指令块中
    symtab->currentFunc->getInterCode().addInstFirst(temp);

    // 创建临时变量保存IR的值，以及线性IR指令
    node->blockInsts.addInst(left->blockInsts);
    node->blockInsts.addInst(right->blockInsts);
    node->blockInsts.addInst(new BinaryIRInst(IRInstOperator::IRINST_OP_SUB_I, resultValue, left->val, right->val));
    node->val = resultValue;

    return true;
}

/// @brief 整数乘法AST节点翻译成线性中间IR
/// @param node AST节点
/// @return 翻译是否成功，true：成功，false：失败
bool IRGenerator::ir_mul(ast_node* node) {
    ast_node* src1 = node->sons[0];    // 第一操作数节点
    ast_node* src2 = node->sons[1];    // 第二个操作数节点

    // 乘法节点，左结合，先计算左节点，后计算右节点

    // 先遍历最左侧的 节点并生成 相关的 ircode 信息
    src1 = ir_visit_ast_node(src1);
    if(!src1) {
        // 左侧的中间代码过程产生了错误，终止
        // AST 语法树的遍历过程
        return false;
    }

    // 乘法的右边的操作数
    src2 = ir_visit_ast_node(src2);
        if(!src2) {
        // 左侧的中间代码过程产生了错误，终止
        // AST 语法树的遍历过程
        return false;
    }

    Value* resultValue = symtab->currentFunc->newTempValue(BasicType::TYPE_INT);
    // 同时向函数中添加 相关变量的声明指令
    IRInst* temp = new DeclareIRInst(resultValue);
    // 将当前的临时变量的声明指令添加到 当前函数的指令块中
    symtab->currentFunc->getInterCode().addInstFirst(temp);

    // 创建临时变量保存 IR 的值，以及线性 IR 的指令
    node->blockInsts.addInst(src1->blockInsts);
    node->blockInsts.addInst(src2->blockInsts);
    node->blockInsts.addInst(new BinaryIRInst(IRInstOperator::IRINST_OP_MUL_I, resultValue, src1->val, src2->val));
    node->val = resultValue;

    return true;
}

/// @brief 整数乘法AST节点翻译成线性中间IR
/// @param node AST节点
/// @return 翻译是否成功，true：成功，false：失败
bool IRGenerator::ir_div(ast_node* node) {
    ast_node* src1 = node->sons[0];    // 第一操作数节点
    ast_node* src2 = node->sons[1];    // 第二个操作数节点

    // 乘法节点，左结合，先计算左节点，后计算右节点

    // 先遍历最左侧的 节点并生成 相关的 ircode 信息
    src1 = ir_visit_ast_node(src1);
    if(!src1) {
        // 左侧的中间代码过程产生了错误，终止
        // AST 语法树的遍历过程
        return false;
    }

    // 乘法的右边的操作数
    src2 = ir_visit_ast_node(src2);
        if(!src2) {
        // 左侧的中间代码过程产生了错误，终止
        // AST 语法树的遍历过程
        return false;
    }

    Value* resultValue = symtab->currentFunc->newTempValue(BasicType::TYPE_INT);
    // 同时向函数中添加 相关变量的声明指令
    IRInst* temp = new DeclareIRInst(resultValue);
    // 将当前的临时变量的声明指令添加到 当前函数的指令块中
    symtab->currentFunc->getInterCode().addInstFirst(temp);

    // 创建临时变量保存 IR 的值，以及线性 IR 的指令
    node->blockInsts.addInst(src1->blockInsts);
    node->blockInsts.addInst(src2->blockInsts);
    node->blockInsts.addInst(new BinaryIRInst(IRInstOperator::IRINST_OP_DIV_I, resultValue, src1->val, src2->val));
    node->val = resultValue;

    return true;
}

/// @brief 整数乘法AST节点翻译成线性中间IR
/// @param node AST节点
/// @return 翻译是否成功，true：成功，false：失败
bool IRGenerator::ir_mod(ast_node* node) {
    ast_node* src1 = node->sons[0];    // 第一操作数节点
    ast_node* src2 = node->sons[1];    // 第二个操作数节点

    // 乘法节点，左结合，先计算左节点，后计算右节点

    // 先遍历最左侧的 节点并生成 相关的 ircode 信息
    src1 = ir_visit_ast_node(src1);
    if(!src1) {
        // 左侧的中间代码过程产生了错误，终止
        // AST 语法树的遍历过程
        return false;
    }

    // 乘法的右边的操作数
    src2 = ir_visit_ast_node(src2);
        if(!src2) {
        // 左侧的中间代码过程产生了错误，终止
        // AST 语法树的遍历过程
        return false;
    }

    Value* resultValue = symtab->currentFunc->newTempValue(BasicType::TYPE_INT);
    // 同时向函数中添加 相关变量的声明指令
    IRInst* temp = new DeclareIRInst(resultValue);
    // 将当前的临时变量的声明指令添加到 当前函数的指令块中
    symtab->currentFunc->getInterCode().addInstFirst(temp);

    // 创建临时变量保存 IR 的值，以及线性 IR 的指令
    node->blockInsts.addInst(src1->blockInsts);
    node->blockInsts.addInst(src2->blockInsts);
    node->blockInsts.addInst(new BinaryIRInst(IRInstOperator::IRISNT_OP_MOD_I, resultValue, src1->val, src2->val));
    node->val = resultValue;

    return true;
}

/// @brief 小于AST节点翻译成线性中间IR
/// @param node AST节点
/// @return 翻译是否成功，true：成功，false：失败
bool IRGenerator::ir_lt(ast_node* node) {
    ast_node* src1 = node->sons[0];    // 第一操作数节点
    ast_node* src2 = node->sons[1];    // 第二个操作数节点

    // 乘法节点，左结合，先计算左节点，后计算右节点

    // 先遍历最左侧的 节点并生成 相关的 ircode 信息
    src1 = ir_visit_ast_node(src1);
    if(!src1) {
        // 左侧的中间代码过程产生了错误，终止
        // AST 语法树的遍历过程
        return false;
    }

    // 乘法的右边的操作数
    src2 = ir_visit_ast_node(src2);
        if(!src2) {
        // 左侧的中间代码过程产生了错误，终止
        // AST 语法树的遍历过程
        return false;
    }

    Value* resultValue = symtab->currentFunc->newTempValue(BasicType::TYPE_BOOL);
    // 同时向函数中添加 相关变量的声明指令
    IRInst* temp = new DeclareIRInst(resultValue);
    // 将当前的临时变量的声明指令添加到 当前函数的指令块中
    symtab->currentFunc->getInterCode().addInstFirst(temp);

    // 创建临时变量保存 IR 的值，以及线性 IR 的指令
    node->blockInsts.addInst(src1->blockInsts);
    node->blockInsts.addInst(src2->blockInsts);
    node->blockInsts.addInst(new BinaryIRInst(IRInstOperator::IRISNT_OP_LT_I, resultValue, src1->val, src2->val));
    node->val = resultValue;

    return true;
}

/// @brief 小于等于AST节点翻译成线性中间IR
/// @param node AST节点
/// @return 翻译是否成功，true：成功，false：失败
bool IRGenerator::ir_le(ast_node* node) {
    ast_node* src1 = node->sons[0];    // 第一操作数节点
    ast_node* src2 = node->sons[1];    // 第二个操作数节点

    // 乘法节点，左结合，先计算左节点，后计算右节点

    // 先遍历最左侧的 节点并生成 相关的 ircode 信息
    src1 = ir_visit_ast_node(src1);
    if(!src1) {
        // 左侧的中间代码过程产生了错误，终止
        // AST 语法树的遍历过程
        return false;
    }

    // 乘法的右边的操作数
    src2 = ir_visit_ast_node(src2);
        if(!src2) {
        // 左侧的中间代码过程产生了错误，终止
        // AST 语法树的遍历过程
        return false;
    }

    Value* resultValue = symtab->currentFunc->newTempValue(BasicType::TYPE_BOOL);
    // 同时向函数中添加 相关变量的声明指令
    IRInst* temp = new DeclareIRInst(resultValue);
    // 将当前的临时变量的声明指令添加到 当前函数的指令块中
    symtab->currentFunc->getInterCode().addInstFirst(temp);

    // 创建临时变量保存 IR 的值，以及线性 IR 的指令
    node->blockInsts.addInst(src1->blockInsts);
    node->blockInsts.addInst(src2->blockInsts);
    node->blockInsts.addInst(new BinaryIRInst(IRInstOperator::IRISNT_OP_LE_I, resultValue, src1->val, src2->val));
    node->val = resultValue;

    return true;
}

/// @brief 小于等于AST节点翻译成线性中间IR
/// @param node AST节点
/// @return 翻译是否成功，true：成功，false：失败
bool IRGenerator::ir_gt(ast_node* node) {
    ast_node* src1 = node->sons[0];    // 第一操作数节点
    ast_node* src2 = node->sons[1];    // 第二个操作数节点

    // 乘法节点，左结合，先计算左节点，后计算右节点

    // 先遍历最左侧的 节点并生成 相关的 ircode 信息
    src1 = ir_visit_ast_node(src1);
    if(!src1) {
        // 左侧的中间代码过程产生了错误，终止
        // AST 语法树的遍历过程
        return false;
    }

    // 乘法的右边的操作数
    src2 = ir_visit_ast_node(src2);
        if(!src2) {
        // 左侧的中间代码过程产生了错误，终止
        // AST 语法树的遍历过程
        return false;
    }

    Value* resultValue = symtab->currentFunc->newTempValue(BasicType::TYPE_BOOL);
    // 同时向函数中添加 相关变量的声明指令
    IRInst* temp = new DeclareIRInst(resultValue);
    // 将当前的临时变量的声明指令添加到 当前函数的指令块中
    symtab->currentFunc->getInterCode().addInstFirst(temp);

    // 创建临时变量保存 IR 的值，以及线性 IR 的指令
    node->blockInsts.addInst(src1->blockInsts);
    node->blockInsts.addInst(src2->blockInsts);
    node->blockInsts.addInst(new BinaryIRInst(IRInstOperator::IRISNT_OP_GT_I, resultValue, src1->val, src2->val));
    node->val = resultValue;

    return true;
}

/// @brief 小于等于AST节点翻译成线性中间IR
/// @param node AST节点
/// @return 翻译是否成功，true：成功，false：失败
bool IRGenerator::ir_ge(ast_node* node) {
    ast_node* src1 = node->sons[0];    // 第一操作数节点
    ast_node* src2 = node->sons[1];    // 第二个操作数节点

    // 乘法节点，左结合，先计算左节点，后计算右节点

    // 先遍历最左侧的 节点并生成 相关的 ircode 信息
    src1 = ir_visit_ast_node(src1);
    if(!src1) {
        // 左侧的中间代码过程产生了错误，终止
        // AST 语法树的遍历过程
        return false;
    }

    // 乘法的右边的操作数
    src2 = ir_visit_ast_node(src2);
        if(!src2) {
        // 左侧的中间代码过程产生了错误，终止
        // AST 语法树的遍历过程
        return false;
    }

    Value* resultValue = symtab->currentFunc->newTempValue(BasicType::TYPE_BOOL);
    // 同时向函数中添加 相关变量的声明指令
    IRInst* temp = new DeclareIRInst(resultValue);
    // 将当前的临时变量的声明指令添加到 当前函数的指令块中
    symtab->currentFunc->getInterCode().addInstFirst(temp);

    // 创建临时变量保存 IR 的值，以及线性 IR 的指令
    node->blockInsts.addInst(src1->blockInsts);
    node->blockInsts.addInst(src2->blockInsts);
    node->blockInsts.addInst(new BinaryIRInst(IRInstOperator::IRISNT_OP_GE_I, resultValue, src1->val, src2->val));
    node->val = resultValue;

    return true;
}

/// @brief 小于等于AST节点翻译成线性中间IR
/// @param node AST节点
/// @return 翻译是否成功，true：成功，false：失败
bool IRGenerator::ir_eq(ast_node* node) {
    ast_node* src1 = node->sons[0];    // 第一操作数节点
    ast_node* src2 = node->sons[1];    // 第二个操作数节点

    // 乘法节点，左结合，先计算左节点，后计算右节点

    // 先遍历最左侧的 节点并生成 相关的 ircode 信息
    src1 = ir_visit_ast_node(src1);
    if(!src1) {
        // 左侧的中间代码过程产生了错误，终止
        // AST 语法树的遍历过程
        return false;
    }

    // 乘法的右边的操作数
    src2 = ir_visit_ast_node(src2);
        if(!src2) {
        // 左侧的中间代码过程产生了错误，终止
        // AST 语法树的遍历过程
        return false;
    }

    Value* resultValue = symtab->currentFunc->newTempValue(BasicType::TYPE_BOOL);
    // 同时向函数中添加 相关变量的声明指令
    IRInst* temp = new DeclareIRInst(resultValue);
    // 将当前的临时变量的声明指令添加到 当前函数的指令块中
    symtab->currentFunc->getInterCode().addInstFirst(temp);

    // 创建临时变量保存 IR 的值，以及线性 IR 的指令
    node->blockInsts.addInst(src1->blockInsts);
    node->blockInsts.addInst(src2->blockInsts);
    node->blockInsts.addInst(new BinaryIRInst(IRInstOperator::IRISNT_OP_EQ_I, resultValue, src1->val, src2->val));
    node->val = resultValue;

    return true;
}

/// @brief 小于等于AST节点翻译成线性中间IR
/// @param node AST节点
/// @return 翻译是否成功，true：成功，false：失败
bool IRGenerator::ir_ne(ast_node* node) {
    ast_node* src1 = node->sons[0];    // 第一操作数节点
    ast_node* src2 = node->sons[1];    // 第二个操作数节点

    // 乘法节点，左结合，先计算左节点，后计算右节点

    // 先遍历最左侧的 节点并生成 相关的 ircode 信息
    src1 = ir_visit_ast_node(src1);
    if(!src1) {
        // 左侧的中间代码过程产生了错误，终止
        // AST 语法树的遍历过程
        return false;
    }

    // 乘法的右边的操作数
    src2 = ir_visit_ast_node(src2);
        if(!src2) {
        // 左侧的中间代码过程产生了错误，终止
        // AST 语法树的遍历过程
        return false;
    }

    Value* resultValue = symtab->currentFunc->newTempValue(BasicType::TYPE_BOOL);
    // 同时向函数中添加 相关变量的声明指令
    IRInst* temp = new DeclareIRInst(resultValue);
    // 将当前的临时变量的声明指令添加到 当前函数的指令块中
    symtab->currentFunc->getInterCode().addInstFirst(temp);

    // 创建临时变量保存 IR 的值，以及线性 IR 的指令
    node->blockInsts.addInst(src1->blockInsts);
    node->blockInsts.addInst(src2->blockInsts);
    node->blockInsts.addInst(new BinaryIRInst(IRInstOperator::IRISNT_OP_NE_I, resultValue, src1->val, src2->val));
    node->val = resultValue;

    return true;
}

/// @brief 逻辑表达式与的AST节点翻译成线性中间IR
/// @param node AST节点
/// @return 翻译是否成功，true：成功，false：失败
bool IRGenerator::ir_and(ast_node* node) {
    // 逻辑与是一种 二元运算 操作, 其子树可以近似看成二叉树
    ast_node* left = node->sons[0];
    ast_node* right = node->sons[1];

    // 遍历左子树
    left->trueInst = node->trueInst;
    left->falseInst = node->falseInst;
    left = ir_visit_ast_node(left);
    if(!left) {
        std::cout << "与操作的 左侧 表达式存在着错误" << std::endl;
        return false;
    }

    // 此时，我们就要开始创建 有条件跳转语句
    IRInst* next = new LabelIRInst();
    IRInst* jmpc;
    // 告知 要进行 真假反转
    if(left->trueInst == node->falseInst) {
        jmpc = new JmpcIRInst(left->val, node->falseInst, next);
    } else {
        jmpc = new JmpcIRInst(left->val, next, node->falseInst);
    }
    // 添加指令
    node->blockInsts.addInst(left->blockInsts);
    node->blockInsts.addInst(jmpc);
    node->blockInsts.addInst(next);

    // 遍历右子树
    right->trueInst = node->trueInst;
    right->falseInst = node->falseInst;
    right = ir_visit_ast_node(right);
    if(!right) {
        std::cout << "与操作的 右侧 表达式存在着错误" << std::endl;
        return false;
    }
    // 右侧代码块加入到当前的节点中
    node->blockInsts.addInst(right->blockInsts);

    // 与 运算的 值应该 取右子树的值
    node->val = right->val;

    return true;
}

/// @brief 逻辑表达式与的AST节点翻译成线性中间IR
/// @param node AST节点
/// @return 翻译是否成功，true：成功，false：失败
bool IRGenerator::ir_or(ast_node* node) {
    // 逻辑与是一种 二元运算 操作, 其子树可以近似看成二叉树
    ast_node* left = node->sons[0];
    ast_node* right = node->sons[1];

    // 遍历左子树
    left->trueInst = node->trueInst;
    left->falseInst = node->falseInst;
    left = ir_visit_ast_node(left);
    if(!left) {
        std::cout << "或操作的 左侧 表达式存在着错误" << std::endl;
        return false;
    }

    // 此时，我们就要开始创建 有条件跳转语句
    IRInst* next = new LabelIRInst();
    IRInst* jmpc;
    // 告知 要进行 真假反转
    if(left->trueInst == node->falseInst) {
        jmpc = new JmpcIRInst(left->val, next, node->trueInst);
    } else {
        jmpc = new JmpcIRInst(left->val, node->trueInst, next);
    }
    
    // 添加指令
    node->blockInsts.addInst(left->blockInsts);
    node->blockInsts.addInst(jmpc);
    node->blockInsts.addInst(next);

    // 遍历右子树
    right->trueInst = node->trueInst;
    right->falseInst = node->falseInst;
    right = ir_visit_ast_node(right);
    if(!right) {
        std::cout << "或操作的 右侧 表达式存在着错误" << std::endl;
        return false;
    }
    // 右侧代码块加入到当前的节点中
    node->blockInsts.addInst(right->blockInsts);

    // 与 运算的 值应该 取右子树的值
    node->val = right->val;
    node->trueInst = right->trueInst;
    node->falseInst = right->falseInst;

    return true;
}


/// @brief 逻辑表达式与的AST节点翻译成线性中间IR
/// @param node AST节点
/// @return 翻译是否成功，true：成功，false：失败
bool IRGenerator::ir_not(ast_node* node) {
    // 逻辑非是一个一元运算符，主要的功能就是 通知 父节点 和 子节点
    // 真假 目标指令的 反转切换
    IRInst* tmp = node->trueInst;
    node->trueInst = node->falseInst;
    node->falseInst = tmp;

    // 遍历子节点的值
    ast_node* child = node->sons[0];
    child->trueInst = node->trueInst;
    child->falseInst = node->falseInst;
    child = ir_visit_ast_node(child);
    if(!child) {
        std::cout << "逻辑非的子表达式出现了错误" << std::endl;
        return false;   // 语法错误
    }
    node->blockInsts.addInst(child->blockInsts);
    node->val = child->val;
    return true;
}

/// @brief if_condition 块会依据最后一次的 值进行 一次变量封装操作
///        会动态生成 最后一个 有条件跳转指令
bool IRGenerator::ir_if_condition(ast_node* node) {
    ast_node* logic_expr = node->sons[0];
    // 遍历该节点
    // if 和 while 的条件继续向下传传递
    logic_expr->trueInst = node->trueInst;
    logic_expr->falseInst = node->falseInst;
    logic_expr = ir_visit_ast_node(logic_expr);
    if(!logic_expr) return false;   // 出错

    // 目前先简单的不考虑 与或非 短路求值
    node->val = logic_expr->val;
    node->blockInsts.addInst(logic_expr->blockInsts);
    IRInst* jmpc;
    if(logic_expr->trueInst == node->falseInst) {
        jmpc = new JmpcIRInst(logic_expr->val, node->falseInst, node->trueInst); 
    } else {
        jmpc = new JmpcIRInst(logic_expr->val, node->trueInst, node->falseInst); 
    }
    node->blockInsts.addInst(jmpc);
    return true;
}

/// @brief while语句块 AST节点翻译成线性中间IR
/// @param node AST节点
/// @return 翻译是否成功，true：成功，false：失败
bool IRGenerator::ir_while(ast_node* node) {
    /**
     * while 节点的子树图：
     *        while
     *        /   \
     *      cond  stmt
     * while 自身部分的线性 ir 可视化：
     *  1. loop begining
     *     这个部分主要是 cond 的语句块部分
     *  2. loop body
     *     这个部分主要是 stmt 的语句块部分
     *  3. loop exit
     */
     ast_node* cond = node->sons[0];
     ast_node* stmt = node->sons[1];

     // 创建 3 个标签指令
     IRInst* begin = new LabelIRInst();
     IRInst* body = new LabelIRInst();
     IRInst* exit = new LabelIRInst();

    cond->trueInst = body;
    cond->falseInst = exit;
    // 生成条件语句块的 中间 ir 指令
    cond = ir_visit_ast_node(cond);
    if(!cond) {
        std::cout << "while 语句的条件中出现了 ir 生成时的错误" << std::endl;
        return false;
    }

    // 生成 whiLe 语句块中 的线性 ir 指令
    stmt = ir_visit_ast_node(stmt);
    if(!stmt) {
        std::cout << "while 语句的 块级语句中出现 ir 生成时的错误" << std::endl;
        return false;
    }

    // 组装各个部分的指令块
    node->blockInsts.addInst(begin);
    node->blockInsts.addInst(cond->blockInsts);
    node->blockInsts.addInst(body);
    node->blockInsts.addInst(stmt->blockInsts);
    // 注意此时，我们需要向 statement 语句的最后一步增加 无条件跳转到循环体的开头
    IRInst* br = new GotoIRInst(begin);
    node->blockInsts.addInst(br);
    node->blockInsts.addInst(exit);

     return true;
}

/// @brief if语句 AST节点翻译成线性中间IR
/// @param node AST节点
/// @return 翻译是否成功，true：成功，false：失败
bool IRGenerator::ir_if(ast_node* node) {
    ast_node* cond = node->sons[0];
    ast_node* stmt = node->sons[1];
    ast_node* els = node->sons[2];
    
    IRInst* targetT = new LabelIRInst(); // 无参表示根据上下文自动选择标签名
    IRInst* targetF = new LabelIRInst();
    IRInst* exitIf  = new LabelIRInst();

    // 采用 后序遍历 
    cond->trueInst = targetT;
    cond->falseInst = targetF;
    cond = ir_visit_ast_node(cond);
    if(cond == nullptr) {
        // 出现语法错误
        return false;
    }

    stmt = ir_visit_ast_node(stmt);
    if(stmt == nullptr) {
        // 出现语法错误
        return false;
    }

    // 组织 各个代码片段并生成 if 语句快的代码块 => 有条件跳转
    node->blockInsts.addInst(cond->blockInsts);
    // if 条件为 真的 语句
    node->blockInsts.addInst(targetT);
    node->blockInsts.addInst(stmt->blockInsts);
    // if 条件为假的语句
    node->blockInsts.addInst(targetF);
    // else 语句所在分支的解析
    if(els != nullptr) {
        els->trueInst = targetT;
        els->falseInst = targetF;
        // 遍历 else 节点 所在的分支
        els->exitInst = exitIf;
        els = ir_visit_ast_node(els);
        if(els == nullptr)  // 出现错误 
            return false;
        node->blockInsts.addInst(els->blockInsts);
    }
    node->blockInsts.addInst(exitIf);

    return true;
}

bool IRGenerator::ir_else(ast_node* node) {
    // TODO: no implementation
    ast_node* stmt = node->sons[0];  // 结束时，无条件跳转到与之匹配 if 语句的出口处

    // 遍历唯一的子节点并退出if 语句
    stmt = ir_visit_ast_node(stmt);
    if(stmt == nullptr) return false;

    // 添加指令
    node->blockInsts.addInst(stmt->blockInsts);
    // 创建无条件跳转指令
    GotoIRInst* br = new GotoIRInst(node->exitInst);
    node->blockInsts.addInst(br);
    // 同时需要向 else 的父节点 If 的 真语句处添加 无条件跳转指令
    node->parent->blockInsts.addInstOff(1, br);
    
    return true;
}

/// @brief 赋值AST节点翻译成线性中间IR
/// @param node AST节点
/// @return 翻译是否成功，true：成功，false：失败
bool IRGenerator::ir_assign(ast_node * node)
{
    ast_node * son1_node = node->sons[0];
    ast_node * son2_node = node->sons[1];

    // 赋值节点，自右往左运算

    // 赋值运算符的左侧操作数
    ast_node * left = ir_visit_ast_node(son1_node);
    if (!left) {
        // 某个变量没有定值
        // 这里缺省设置变量不存在则创建，因此这里不会错误
        return false;
    }

    // 赋值运算符的右侧操作数
    ast_node * right = ir_visit_ast_node(son2_node);
    if (!right) {
        // 某个变量没有定值
        return false;
    }

    // 这里只处理整型的数据，如需支持实数，则需要针对类型进行处理
    // TODO real number add

    // 创建临时变量保存IR的值，以及线性IR指令
    node->blockInsts.addInst(right->blockInsts);
    node->blockInsts.addInst(left->blockInsts);
    node->blockInsts.addInst(new AssignIRInst(left->val, right->val));

    // 这里假定赋值的类型是一致的
    left->val->type = right->val->type;
    node->val = left->val;

    return true;
}

/// @brief return节点翻译成线性中间IR
/// @param node AST节点
/// @return 翻译是否成功，true：成功，false：失败
bool IRGenerator::ir_return(ast_node * node)
{
    ast_node * right = nullptr;

    // return语句可能没有没有表达式，也可能有，因此这里必须进行区分判断
    if (!node->sons.empty()) {

        ast_node * son_node = node->sons[0];

        // 返回的表达式的指令保存在right节点中
        right = ir_visit_ast_node(son_node);
        if (!right) {

            // 某个变量没有定值
            return false;
        }
    }

    // 这里只处理整型的数据，如需支持实数，则需要针对类型进行处理

    // 创建临时变量保存IR的值，以及线性IR指令
    node->blockInsts.addInst(right->blockInsts);

    // 返回值赋值到函数返回值变量上，然后跳转到函数的尾部
    node->blockInsts.addInst(new AssignIRInst(symtab->currentFunc->getReturnValue(), right->val));

    // 跳转到函数的尾部出口指令上
    node->blockInsts.addInst(new GotoIRInst(symtab->currentFunc->getExitLabel()));

    node->val = right->val;

    // 这里设置返回值类型
    ValueType & returnType = symtab->currentFunc->getReturnType();
    if (returnType.type == BasicType::TYPE_VOID) {
        // 设置类型
        returnType.type = right->val->type.type;
    } else if (returnType.type != right->val->type.type) {
        // 两者类型不一致，要出错显示
        // 或者隐式转换成更高的类型
        // TODO 这里目前什么都不做
    }

    return true;
}

/// @brief 标识符叶子节点翻译成线性中间IR
/// @param node AST节点
/// @return 翻译是否成功，true：成功，false：失败
bool IRGenerator::ir_leaf_node_var_id(ast_node * node)
{
    Value * val;

    // 新建一个ID型Value

    // 变量，则需要在符号表中查找对应的值
    // 若变量之前没有有定值，则采用默认的值为0

    // 这需要确定是否是变量声明，如果是变量声明，则我们需要查找
    // 变量的定义，如果是 变量的使用，我们一定已经在之前声明过了这个变量，
    // 否则，这是一定是变量未声明而直接使用的错误
    if(symtab->currentFunc == nullptr) {
        // 全局变量在符号表中查找
        val = symtab->findValue(node->name);
        // std::cout << "执行了全局变量表中变量的查找" << std::endl; 
    } else {
        // 函数中的标志中在当前函数作用域中查找
        val = symtab->currentFunc->findValue(node->name, false);
        // std::cout << "执行了函数中变量的查找" << std::endl; 
    }

    bool declare = (node->parent->node_type == ast_operator_type::AST_OP_VARDECL) 
                || (node->parent->node_type == ast_operator_type::AST_OP_VARINIT);

    // std::cout << "declare的值为： " << declare << std::endl;
    // bool isEmpty = val == nullptr;
    // std::cout << "此时的 val 的值是否为空指针 " << isEmpty << std::endl; 

    if(!declare && !val) {
        std::cout << "源代码的第"  << node->line_no << "行的符号 " << node->name 
                  << " 未声明而直接使用" << std::endl; 
        return false;
    } else if(declare && !val) {
        // 变量的注册应该由 变量声明节点来完成
        val = new VarValue(node->name, BasicType::TYPE_INT);
    } else if(declare && val) {
        std::cout << "变量 " << node->name <<  " 出现重复声明" << std::endl; 
        return false;
    }

    node->val = val;

    return true;
}

bool IRGenerator::ir_leaf_node_var_type(ast_node* node) {
    // 类型名只能是 int 或者 void 用于返回值类型
    if(node->name == "int") {
        node->type = ValueType(BasicType::TYPE_INT);
    } else if(node->name == "void") {
        if(node->parent->node_type != ast_operator_type::AST_OP_FUNC_RETURN) {
            std::cout << "变量声明不支持 void 的类型" << std::endl;
            return false;
        }
        node->type = ValueType(BasicType::TYPE_VOID);
    } else {
        std::cout << "minic 文法中不支持 其他类型的返回值" << std::endl;
        return false;
    }

    return true;
}

/// @brief 无符号整数字面量叶子节点翻译成线性中间IR
/// @param node AST节点
/// @return 翻译是否成功，true：成功，false：失败
bool IRGenerator::ir_leaf_node_uint(ast_node * node)
{
    Value * val;

    // 新建一个整数常量Value
    val = symtab->newConstValue((int32_t) node->integer_val);

    node->val = val;

    return true;
}

/// @brief float数字面量叶子节点翻译成线性中间IR
/// @param node AST节点
/// @return 翻译是否成功，true：成功，false：失败
bool IRGenerator::ir_leaf_node_float(ast_node * node)
{
    Value * val = nullptr;

    // 新建一个实数型常量Value
    val = symtab->newConstValue(node->float_val);

    node->val = val;

    return true;
}

/// @brief 未知节点类型的节点处理
/// @param node AST节点
/// @return 翻译是否成功，true：成功，false：失败
bool IRGenerator::ir_default(ast_node * node)
{
    // 未知的节点
    printf("Unkown node(%d)\n", (int) node->node_type);
    return true;
}

/// @brief 根据AST的节点运算符查找对应的翻译函数并执行翻译动作
/// @param node AST节点
/// @return 成功返回node节点，否则返回nullptr
ast_node * IRGenerator::ir_visit_ast_node(ast_node * node)
{
    // 空节点
    if (nullptr == node) {
        return nullptr;
    }

    bool result;

    std::unordered_map<ast_operator_type, ast2ir_handler_t>::const_iterator pIter;
    pIter = ast2ir_handlers.find(node->node_type);
    if (pIter == ast2ir_handlers.end()) {
        // 没有找到，则说明当前不支持
        result = (this->ir_default)(node);
    } else {
        result = (this->*(pIter->second))(node);
    }

    if (!result) {
        // 语义解析错误，则出错返回
        node = nullptr;
    }

    return node;
}

/// @brief 遍历抽象语法树产生线性IR，保存到IRCode中
/// @param root 抽象语法树
/// @param IRCode 线性IR
/// @return true: 成功 false: 失败
bool IRGenerator::run()
{
    ast_node * node;

    // 从根节点进行遍历
    node = ir_visit_ast_node(root);

    return node != nullptr;
}
